package cn.sxgan.gen.services.base;

import cn.sxgan.gen.config.DataSourceConfig;
import cn.sxgan.gen.config.DynamicDataSourceContextHolder;
import cn.sxgan.gen.enums.DataSourceType;
import cn.sxgan.gen.enums.ResponseStatus;
import cn.sxgan.gen.exception.ApiException;
import cn.sxgan.gen.model.ColumnInfo;
import cn.sxgan.gen.model.DbTable;
import cn.sxgan.gen.model.GlobalDataSource;
import cn.sxgan.gen.utils.CommonUtils;
import cn.sxgan.gen.utils.JdbcTypeConverterUtils;
import cn.sxgan.gen.utils.Result;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @Description: 数据源服务
 * @Author: sxgan
 * @Date: 2025-07-19 09:58
 * @Version: 1.0
 **/
@Slf4j
@Service
public class DataSourceService {
    
    @Autowired
    DataSourceConfig dataSourceConfig;
    @Autowired
    DataSourceQueryFactory dataSourceQueryFactory;
    
    public List<GlobalDataSource> getAllDataSources() {
        List<GlobalDataSource> allDataSourceInfo = dataSourceConfig.getAllDataSourceInfo();
        log.info("查询当前数据源列表条数:{}条", allDataSourceInfo.size());
        return allDataSourceInfo;
    }
    
    public GlobalDataSource getActiveDataSource() {
        return dataSourceConfig.getActiveDataSource();
    }
    
    // 注册新数据源并切换
    public void addDatasource(String key, String url, String username, String password, String driverClass) {
        DataSource newDataSource = dataSourceConfig.createDataSource(url, username, password, driverClass);
        // 验证数据源连接
        getConnectionWithRetry(newDataSource);
        // 添加数据源
        dataSourceConfig.addDataSource(key, newDataSource);
        DynamicDataSourceContextHolder.setDataSourceKey(key);
    }
    
    
    // 新增方法：验证数据源连接
    private void validateDataSourceConnection(DataSource dataSource) {
        try {
            // 尝试获取连接（测试物理连接）
            Connection connection = dataSource.getConnection();
            // 执行简单查询验证连接有效性
            connection.createStatement().execute("SELECT 1");
            
        } catch (SQLException e) {
            // 关闭无效数据源（防止资源泄漏）
            if (dataSource instanceof DruidDataSource) {
                ((DruidDataSource) dataSource).close();
            }
            // 包装并抛出业务异常
            throw new ApiException(ResponseStatus.FAIL.getResponseCode(), "数据源连接验证失败！");
        }
    }
    
    // 切换回默认数据源
    public void switchToDefault() {
        DynamicDataSourceContextHolder.setDataSourceKey("default");
    }
    
    // 移除数据源
    public void removeDataSource(String key) {
        dataSourceConfig.removeDataSource(key);
    }
    
    public void getConnectionWithRetry(DataSource dataSource) {
        try {
            // 尝试获取连接
            dataSource.getConnection();
        } catch (SQLException e) {
            log.warn("获取数据库连接失败");
            // 分析具体错误类型
            String errorMsg = "数据库连接失败: ";
            if (e.getMessage().contains("Connection timed out")) {
                errorMsg += "网络连接超时，请检查数据库地址和端口";
            } else if (e.getMessage().contains("Access denied")) {
                errorMsg += "用户名或密码错误";
            } else if (e.getMessage().contains("No suitable driver")) {
                errorMsg += "数据库驱动未加载";
            } else {
                errorMsg += "服务暂时不可用，请稍后再试";
            }
            // 永远不会执行到这里，保留语法完整性
            throw new ApiException(errorMsg);
        }
    }
    
    /**
     * 获取当前数据库下所有表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    public Result<List<DbTable>> getAllTables(Long pageNum, Long pageSize) {
        GlobalDataSource activeDataSource = getActiveDataSource();
        DataSourceType dataSourceTypeEnum = DataSourceType.getEnumValue(activeDataSource.getDbType());
        if (dataSourceTypeEnum == null) {
            throw new ApiException("不支持的数据库类型");
        }
        DataSourceQuery dataSourceQuery = dataSourceQueryFactory.getDataSourceQuery(dataSourceTypeEnum);
        // List<ColumnInfo> sysUser = dataSourceQuery.getTableColumns("sys_user");
        List<DbTable> dbTables = dataSourceQuery.selectDbTables(null);
        log.info("查询当前数据库下所有表条数:{}条", dbTables.size());
        for (DbTable dbTable : dbTables) {
            for (ColumnInfo columnInfo : dbTable.getColumnInfos()) {
                columnInfo.setJavaName(CommonUtils.convertToCamelCase(columnInfo.getName(), false));
                columnInfo.setJavaType(JdbcTypeConverterUtils.convertToJavaType(columnInfo.getType()));
            }
        }
        List<DbTable> list = dbTables.stream().skip((pageNum - 1) * pageSize).limit(pageSize).toList();
        return Result.success(list, dbTables.size());
    }
}
